package elasticsearch

import (
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"time"

	"bytes"

	s "gitee.com/xiaoa7/jsetl/service"
	jsvmcore "gitee.com/xiaoa7/jsvm-core"
	"github.com/dop251/goja"
	"github.com/elastic/go-elasticsearch/v8/esapi"
)

// 获取数据库实例
func getInstance(id string) (*ElasticsearchService, error) {
	if ins := s.GetService(id); ins != nil {
		if _redis, ok := ins.(*ElasticsearchService); ok {
			return _redis, nil
		} else {
			return nil, errors.New("Elasticsearch instance type error")
		}
	}
	return nil, errors.New("can't find elasticsearch instance")
}

// 样例方法
func (d *ElasticsearchService) SayHello(name string) string {
	return fmt.Sprintf("Hello,%s!", name)
}

// createIndex 创建索引
func (e *ElasticsearchService) createIndex(indexName string, settingsMap map[string]interface{}) error {
	// 准备请求体
	reqBody := map[string]interface{}{
		"settings": settingsMap,
	}
	reqBodyJSON, err := json.Marshal(reqBody)
	if err != nil {
		return fmt.Errorf("序列化请求体失败: %v", err)
	}
	// 创建请求
	req := esapi.IndicesCreateRequest{
		Index: indexName,
		Body:  bytes.NewBuffer(reqBodyJSON),
	}
	// 执行请求
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()
	res, err := req.Do(ctx, e.client)
	if err != nil {
		return fmt.Errorf("创建索引失败: %v", err)
	}
	defer res.Body.Close()
	// 处理响应
	var result map[string]interface{}
	if err := json.NewDecoder(res.Body).Decode(&result); err != nil {
		return fmt.Errorf("解析响应失败: %v", err)
	}
	if res.IsError() {
		return fmt.Errorf("创建索引错误: %v", result)
	}
	return nil
}

// 初始化
func init() {
	jsvmcore.RegisterObject("es", map[string]jsvmcore.HandleFn{
		//连接到es服务
		"connect": func(vm *jsvmcore.JsVM) jsvmcore.JsVmFn {
			return func(params ...interface{}) goja.Value {
				if len(params) < 2 {
					return vm.State.ToValue("无效的输入参数")
				}
				esInstance, _ := params[0].(string)
				uri, _ := params[1].(string)
				if err := RegisteService(esInstance, uri); err == nil {
					return vm.State.ToValue("ok")
				} else {
					return vm.State.ToValue(err.Error())
				}
			}
		},
		"createIndex": func(vm *jsvmcore.JsVM) jsvmcore.JsVmFn {
			return func(params ...interface{}) goja.Value {
				if len(params) < 2 {
					return vm.State.ToValue("无效的输入参数")
				}
				esInstance, _ := params[0].(string)
				name, _ := params[1].(string)
				mapping, _ := params[2].(map[string]interface{})
				if ins, err := getInstance(esInstance); err == nil {
					if err = ins.createIndex(name, mapping); err == nil {
						return vm.State.ToValue("ok")
					} else {
						return vm.State.ToValue(err.Error())
					}
				} else {
					return vm.State.ToValue(err.Error())
				}
			}
		},
	})
}
